<template>
  <div class="async-judge-demo">
    <div class="page-header">
      <h2>异步判题演示</h2>
      <p>演示并发处理多个代码提交的能力</p>
    </div>

    <!-- 队列状态 -->
    <div class="queue-status">
      <el-card>
        <template #header>
          <div class="card-header">
            <span>判题队列状态</span>
            <el-button @click="refreshQueueStatus" :loading="refreshing" size="small">
              刷新
            </el-button>
          </div>
        </template>
        <div class="status-grid">
          <div class="status-item">
            <div class="status-label">队列大小</div>
            <div class="status-value">{{ queueStatus.queue_size }}/{{ queueStatus.max_queue_size }}</div>
          </div>
          <div class="status-item">
            <div class="status-label">活跃工作线程</div>
            <div class="status-value">{{ queueStatus.active_workers }}/{{ queueStatus.max_workers }}</div>
          </div>
          <div class="status-item">
            <div class="status-label">等待任务</div>
            <div class="status-value">{{ queueStatus.pending_tasks }}</div>
          </div>
          <div class="status-item">
            <div class="status-label">运行中任务</div>
            <div class="status-value">{{ queueStatus.running_tasks }}</div>
          </div>
          <div class="status-item">
            <div class="status-label">已完成任务</div>
            <div class="status-value">{{ queueStatus.completed_tasks }}</div>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 批量提交区域 -->
    <div class="batch-submit">
      <el-card>
        <template #header>
          <span>批量提交测试</span>
        </template>
        
        <div class="submit-controls">
          <el-form :model="submitForm" label-width="120px">
            <el-form-item label="提交数量">
              <el-input-number 
                v-model="submitForm.count" 
                :min="1" 
                :max="20" 
                controls-position="right"
              />
            </el-form-item>
            <el-form-item label="编程语言">
              <el-select v-model="submitForm.language">
                <el-option label="Python" value="python" />
                <el-option label="C++" value="cpp" />
                <el-option label="Java" value="java" />
              </el-select>
            </el-form-item>
            <el-form-item label="代码模板">
              <el-select v-model="submitForm.template">
                <el-option label="简单加法" value="add" />
                <el-option label="斐波那契" value="fibonacci" />
                <el-option label="排序算法" value="sort" />
                <el-option label="错误代码" value="error" />
              </el-select>
            </el-form-item>
          </el-form>
          
          <div class="action-buttons">
            <el-button 
              type="primary" 
              @click="batchSubmit" 
              :loading="batchSubmitting"
              :disabled="submitForm.count < 1"
            >
              批量提交 {{ submitForm.count }} 个任务
            </el-button>
            <el-button @click="clearResults">清空结果</el-button>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 任务结果列表 -->
    <div class="task-results">
      <el-card>
        <template #header>
          <div class="card-header">
            <span>任务结果 ({{ tasks.length }})</span>
            <el-button @click="refreshAllTasks" :loading="refreshing" size="small">
              刷新所有
            </el-button>
          </div>
        </template>
        
        <div class="results-list">
          <div 
            v-for="task in tasks" 
            :key="task.task_id" 
            class="task-item"
            :class="getTaskStatusClass(task.status)"
          >
            <div class="task-header">
              <div class="task-id">任务 {{ task.task_id.slice(0, 8) }}</div>
              <div class="task-status">
                <el-tag :type="getStatusTagType(task.status)" size="small">
                  {{ getStatusText(task.status) }}
                </el-tag>
              </div>
            </div>
            
            <div class="task-details">
              <div class="detail-item">
                <span class="label">创建时间:</span>
                <span class="value">{{ formatTime(task.created_at) }}</span>
              </div>
              <div v-if="task.started_at" class="detail-item">
                <span class="label">开始时间:</span>
                <span class="value">{{ formatTime(task.started_at) }}</span>
              </div>
              <div v-if="task.completed_at" class="detail-item">
                <span class="label">完成时间:</span>
                <span class="value">{{ formatTime(task.completed_at) }}</span>
              </div>
              <div v-if="task.result" class="detail-item">
                <span class="label">结果:</span>
                <span class="value">
                  <el-tag :type="getResultTagType(task.result.status)" size="small">
                    {{ task.result.status }}
                  </el-tag>
                  <span v-if="task.result.score !== undefined">
                    ({{ task.result.score }}/{{ task.result.max_score }})
                  </span>
                </span>
              </div>
              <div v-if="task.error_message" class="detail-item">
                <span class="label">错误:</span>
                <span class="value error">{{ task.error_message }}</span>
              </div>
            </div>
          </div>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { submitCodeAsync, getJudgeStatus, getQueueStatus } from '@/api/judge'

// 响应式数据
const queueStatus = ref({
  queue_size: 0,
  max_queue_size: 100,
  active_workers: 0,
  max_workers: 4,
  pending_tasks: 0,
  running_tasks: 0,
  completed_tasks: 0
})

const tasks = ref<any[]>([])
const refreshing = ref(false)
const batchSubmitting = ref(false)

const submitForm = reactive({
  count: 5,
  language: 'python',
  template: 'add'
})

// 代码模板
const codeTemplates = {
  add: {
    python: `def add_numbers(a, b):
    return a + b

# 测试
print(add_numbers(5, 3))`,
    cpp: `#include <iostream>
using namespace std;

int add_numbers(int a, int b) {
    return a + b;
}

int main() {
    cout << add_numbers(5, 3) << endl;
    return 0;
}`,
    java: `public class Main {
    public static int addNumbers(int a, int b) {
        return a + b;
    }
    
    public static void main(String[] args) {
        System.out.println(addNumbers(5, 3));
    }
}`
  },
  fibonacci: {
    python: `def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))`,
    cpp: `#include <iostream>
using namespace std;

int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}

int main() {
    cout << fibonacci(10) << endl;
    return 0;
}`,
    java: `public class Main {
    public static int fibonacci(int n) {
        if (n <= 1) return n;
        return fibonacci(n-1) + fibonacci(n-2);
    }
    
    public static void main(String[] args) {
        System.out.println(fibonacci(10));
    }
}`
  },
  sort: {
    python: `def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr

arr = [64, 34, 25, 12, 22, 11, 90]
print(bubble_sort(arr))`,
    cpp: `#include <iostream>
#include <vector>
using namespace std;

void bubbleSort(vector<int>& arr) {
    int n = arr.size();
    for (int i = 0; i < n-1; i++) {
        for (int j = 0; j < n-i-1; j++) {
            if (arr[j] > arr[j+1]) {
                swap(arr[j], arr[j+1]);
            }
        }
    }
}

int main() {
    vector<int> arr = {64, 34, 25, 12, 22, 11, 90};
    bubbleSort(arr);
    for (int x : arr) cout << x << " ";
    cout << endl;
    return 0;
}`,
    java: `import java.util.Arrays;

public class Main {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n-1; i++) {
            for (int j = 0; j < n-i-1; j++) {
                if (arr[j] > arr[j+1]) {
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}`
  },
  error: {
    python: `def add_numbers(a, b):
    return a + b + 1  # 故意错误

print(add_numbers(5, 3))`,
    cpp: `#include <iostream>
using namespace std;

int add_numbers(int a, int b) {
    return a + b + 1;  // 故意错误
}

int main() {
    cout << add_numbers(5, 3) << endl;
    return 0;
}`,
    java: `public class Main {
    public static int addNumbers(int a, int b) {
        return a + b + 1;  // 故意错误
    }
    
    public static void main(String[] args) {
        System.out.println(addNumbers(5, 3));
    }
}`
  }
}

// 测试用例
const testCases = [
  { input: '5 3', output: '8' },
  { input: '10 20', output: '30' },
  { input: '0 0', output: '0' }
]

// 方法
const refreshQueueStatus = async () => {
  try {
    refreshing.value = true
    const response = await getQueueStatus()
    queueStatus.value = response
  } catch (error: any) {
    ElMessage.error('获取队列状态失败: ' + error.message)
  } finally {
    refreshing.value = false
  }
}

const batchSubmit = async () => {
  try {
    batchSubmitting.value = true
    const newTasks = []
    
    for (let i = 0; i < submitForm.count; i++) {
      const code = codeTemplates[submitForm.template as keyof typeof codeTemplates][submitForm.language as keyof typeof codeTemplates.add]
      
      try {
        const response = await submitCodeAsync({
          problem_id: 1, // 使用第一个题目作为测试
          language: submitForm.language,
          code: code
        })
        
        newTasks.push({
          task_id: response.task_id,
          status: 'pending',
          created_at: Date.now() / 1000
        })
        
        ElMessage.success(`任务 ${i + 1} 提交成功`)
      } catch (error: any) {
        ElMessage.error(`任务 ${i + 1} 提交失败: ${error.message}`)
      }
    }
    
    // 添加到任务列表
    tasks.value.unshift(...newTasks)
    
    // 开始轮询任务状态
    startPolling()
    
  } catch (error: any) {
    ElMessage.error('批量提交失败: ' + error.message)
  } finally {
    batchSubmitting.value = false
  }
}

const refreshAllTasks = async () => {
  try {
    refreshing.value = true
    const promises = tasks.value.map(async (task) => {
      try {
        const status = await getJudgeStatus(task.task_id)
        Object.assign(task, status)
      } catch (error) {
        console.error(`获取任务 ${task.task_id} 状态失败:`, error)
      }
    })
    
    await Promise.all(promises)
  } catch (error: any) {
    ElMessage.error('刷新任务状态失败: ' + error.message)
  } finally {
    refreshing.value = false
  }
}

const clearResults = () => {
  tasks.value = []
}

let pollingInterval: NodeJS.Timeout | null = null

const startPolling = () => {
  if (pollingInterval) {
    clearInterval(pollingInterval)
  }
  
  pollingInterval = setInterval(async () => {
    const pendingTasks = tasks.value.filter(task => 
      task.status === 'pending' || task.status === 'running'
    )
    
    if (pendingTasks.length === 0) {
      clearInterval(pollingInterval!)
      pollingInterval = null
      return
    }
    
    // 刷新队列状态
    await refreshQueueStatus()
    
    // 刷新任务状态
    await refreshAllTasks()
  }, 2000) // 每2秒轮询一次
}

// 工具方法
const getStatusTagType = (status: string) => {
  const typeMap: Record<string, string> = {
    pending: 'info',
    running: 'warning',
    completed: 'success',
    failed: 'danger'
  }
  return typeMap[status] || 'info'
}

const getStatusText = (status: string) => {
  const textMap: Record<string, string> = {
    pending: '等待中',
    running: '运行中',
    completed: '已完成',
    failed: '失败'
  }
  return textMap[status] || status
}

const getTaskStatusClass = (status: string) => {
  return `task-${status}`
}

const getResultTagType = (status: string) => {
  const typeMap: Record<string, string> = {
    AC: 'success',
    WA: 'danger',
    TLE: 'warning',
    MLE: 'warning',
    RE: 'danger',
    CE: 'danger'
  }
  return typeMap[status] || 'info'
}

const formatTime = (timestamp: number) => {
  return new Date(timestamp * 1000).toLocaleTimeString()
}

// 生命周期
onMounted(() => {
  refreshQueueStatus()
})

onUnmounted(() => {
  if (pollingInterval) {
    clearInterval(pollingInterval)
  }
})
</script>

<style scoped lang="scss">
.async-judge-demo {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.page-header {
  text-align: center;
  margin-bottom: 30px;
  
  h2 {
    margin: 0 0 10px 0;
    color: #303133;
  }
  
  p {
    margin: 0;
    color: #909399;
  }
}

.queue-status {
  margin-bottom: 30px;
}

.status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
}

.status-item {
  text-align: center;
  padding: 15px;
  background: #f5f7fa;
  border-radius: 8px;
  
  .status-label {
    font-size: 14px;
    color: #606266;
    margin-bottom: 5px;
  }
  
  .status-value {
    font-size: 24px;
    font-weight: bold;
    color: #303133;
  }
}

.batch-submit {
  margin-bottom: 30px;
}

.submit-controls {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 20px;
}

.action-buttons {
  display: flex;
  gap: 10px;
}

.task-results {
  .results-list {
    max-height: 600px;
    overflow-y: auto;
  }
}

.task-item {
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  margin-bottom: 15px;
  padding: 15px;
  transition: all 0.3s;
  
  &.task-pending {
    border-left: 4px solid #909399;
    background: #fafafa;
  }
  
  &.task-running {
    border-left: 4px solid #e6a23c;
    background: #fdf6ec;
  }
  
  &.task-completed {
    border-left: 4px solid #67c23a;
    background: #f0f9ff;
  }
  
  &.task-failed {
    border-left: 4px solid #f56c6c;
    background: #fef0f0;
  }
}

.task-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  
  .task-id {
    font-weight: bold;
    color: #303133;
  }
}

.task-details {
  .detail-item {
    display: flex;
    margin-bottom: 5px;
    
    .label {
      width: 100px;
      color: #606266;
      font-size: 14px;
    }
    
    .value {
      color: #303133;
      font-size: 14px;
      
      &.error {
        color: #f56c6c;
      }
    }
  }
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
